package com.hengda.museumonline.fragment;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.SyncStateContract;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.Projection;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.VisibleRegion;
import com.amap.api.services.cloud.CloudItem;
import com.amap.api.services.cloud.CloudItemDetail;
import com.amap.api.services.cloud.CloudResult;
import com.amap.api.services.cloud.CloudSearch;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.bumptech.glide.Glide;
import com.hengda.museumonline.R;
import com.hengda.museumonline.adapter.FindAdapter;
import com.hengda.museumonline.entity.MapBean;
import com.hengda.museumonline.rxbus.RxBus;
import com.hengda.museumonline.utils.GlideCircleTransform;
import com.hengda.museumonline.utils.ToastUtil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import rx.Observable;
import rx.functions.Action1;

/**
 * @author：JFWU on 2016/9/27 10:07
 * @E-mail：jeffy12138@126.com
 */
public class FindFragment extends Fragment {
    private FrameLayout fl_content;
    private RecyclerView recyclerView;
    private MapView mMapView;
    private Observable observable;
    private AMap aMap;
    private FloatingActionButton fab;
    private LocationSource.OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private CloudSearch mCloudSearch;
    private CloudSearch.Query mQuery;
    private List<CloudItem> mCloudItems;
    private ArrayList<CloudItem> items = new ArrayList<CloudItem>();
    private ArrayList<CloudItem> cloudItems = new ArrayList<CloudItem>();
    private LatLonPoint mPoint1;
    private LatLonPoint mPoint2;
    private LatLonPoint mPoint3;
    private LatLonPoint mPoint4;
    private LatLonPoint mPoint5;
    private String mTableID = "56f0b05b305a2a3288c02f7e";
    private LatLngBounds latLngBounds;
    private String url;
    private ImageView imageView;
    private double limit = 0.02;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        fl_content = (FrameLayout) inflater.inflate(R.layout.fragment_find, container, false);
        recyclerView = (RecyclerView) fl_content.findViewById(R.id.recyclerview);
        fab = (FloatingActionButton) fl_content.findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
        mMapView = (MapView) fl_content.findViewById(R.id.map);
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState)，实现地图生命周期管理
        mMapView.onCreate(savedInstanceState);
        //初始化地图变量
        if (aMap == null) {
            aMap = mMapView.getMap();
            setUpMap();
            getData();
            searchByBound();
        }
        observable = RxBus.get().register("temp", MapBean.class);
        observable.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                MapBean mapBean = (MapBean) o;
                if (mapBean.isTemp()) {
                    setupRecyclerView(recyclerView);
                    recyclerView.setVisibility(View.VISIBLE);
                    mMapView.setVisibility(View.INVISIBLE);
                } else {
                    setupRecyclerView(recyclerView);
                    recyclerView.setVisibility(View.INVISIBLE);
                    mMapView.setVisibility(View.VISIBLE);
                }
            }
        });


        return fl_content;
    }

    public void searchByBound() {
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                items.clear();
                VisibleRegion visibleRegion = aMap.getProjection().getVisibleRegion(); // 获取可视区域、
                latLngBounds = visibleRegion.latLngBounds;
                mPoint1 = new LatLonPoint(latLngBounds.northeast.latitude, latLngBounds.northeast.longitude);
                mPoint2 = new LatLonPoint(latLngBounds.southwest.latitude, latLngBounds.northeast.longitude);
                mPoint3 = new LatLonPoint(latLngBounds.southwest.latitude, latLngBounds.southwest.longitude);
                mPoint4 = new LatLonPoint(latLngBounds.northeast.latitude, latLngBounds.southwest.longitude);
                mPoint5 = new LatLonPoint(latLngBounds.northeast.latitude, latLngBounds.northeast.longitude);
                List<LatLonPoint> points = new ArrayList<LatLonPoint>();
                points.add(mPoint1);
                points.add(mPoint2);
                points.add(mPoint3);
                points.add(mPoint4);
                points.add(mPoint5);
                CloudSearch.SearchBound bound = new CloudSearch.SearchBound(points);
                try {
                    mQuery = new CloudSearch.Query(mTableID, null, bound);
                    mQuery.setPageSize(100);
                    mCloudSearch.searchCloudAsyn(mQuery);
                } catch (AMapException e) {
                    e.printStackTrace();
                }
            }
        });
        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                marker.showInfoWindow();
                return false;
            }
        });
    }

    private void getData() {
        mCloudSearch = new CloudSearch(getContext());
        mCloudSearch.setOnCloudSearchListener(
                new CloudSearch.OnCloudSearchListener() {
                    @Override
                    public void onCloudSearched(CloudResult result, int rCode) {
                        if (rCode == 1000) {
                            if (result != null && result.getQuery() != null) {
                                if (result.getQuery().equals(mQuery)) {
                                    mCloudItems = result.getClouds();
                                    if (mCloudItems != null && mCloudItems.size() > 0) {
                                        aMap.clear();
                                        for (CloudItem item : mCloudItems) {
                                            if (items.isEmpty()) {
                                                items.add(item);
                                            } else {
                                                if (isAddCloudItem(item)) {
                                                    items.add(item);
                                                }
                                            }
                                        }
                                        for (CloudItem c : items) {
                                            url = c.getCustomfield().get("images_url");
                                            View view = View.inflate(getContext(), R.layout.marker, null);
                                            imageView = (ImageView) view.findViewById(R.id.iv_image);
                                            Glide.with(getContext()).load("http://www.wenbozaixian.com" + url).transform(new GlideCircleTransform(getContext())).into(imageView);
                                            aMap.addMarker(new MarkerOptions()
                                                    .position(new LatLng(c.getLatLonPoint().getLatitude(), c.getLatLonPoint().getLongitude()))
                                                    .title(c.getTitle()).snippet(c.getSnippet())
                                                    .icon(BitmapDescriptorFactory.fromView(view)));

                                        }
                                        System.out.println("数量：" + items.size());
                                    } else {

                                    }
                                }
                            } else {
                                ToastUtil.show(getContext(), "没有搜索到相关数据！");
                            }
                        } else

                        {
                            ToastUtil.showerror(getContext(), rCode);
                        }
                    }

                    @Override
                    public void onCloudItemDetailSearched(CloudItemDetail item, int rCode) {
                    }
                }

        );
    }

    private boolean isAddCloudItem(CloudItem item) {
        for (CloudItem c : items) {
            double distance = getDistanceBetweenTwoPoints(toScreenLocation(item).x, toScreenLocation(item).y,
                    toScreenLocation(c).x, toScreenLocation(c).y);
            if (distance < 160) {
                return false;
            }
        }
        return true;
    }


    /**
     * 两点的距离
     *
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    private double getDistanceBetweenTwoPoints(double x1, double y1, double x2,
                                               double y2) {
        double distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2)
                * (y1 - y2));
        return distance;
    }

    /**
     * 经纬度转像素
     */
    private Point toScreenLocation(CloudItem item) {
        LatLng mLatlng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude());
        return aMap.getProjection().toScreenLocation(mLatlng);

    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.setLocationSource(new LocationSource() {
            @Override
            public void activate(OnLocationChangedListener onLocationChangedListener) {
                mListener = onLocationChangedListener;
                if (mlocationClient == null) {
                    mlocationClient = new AMapLocationClient(getContext());
                    mLocationOption = new AMapLocationClientOption();
                    //设置为高精度定位模式
                    mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                    //设置定位参数
                    mlocationClient.setLocationOption(mLocationOption);
                    // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
                    // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
                    // 在定位结束后，在合适的生命周期调用onDestroy()方法
                    // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
                    //设置定位监听
                    mlocationClient.setLocationListener(new AMapLocationListener() {
                        @Override
                        public void onLocationChanged(AMapLocation amapLocation) {
                            if (mListener != null && amapLocation != null) {
                                if (amapLocation != null && amapLocation.getErrorCode() == 0) {
                                    mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
                                } else {
                                    String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                                }
                            }
                        }
                    });
                    mlocationClient.startLocation();
                }
            }

            @Override
            public void deactivate() {
                mListener = null;
                if (mlocationClient != null) {
                    mlocationClient.stopLocation();
                    mlocationClient.onDestroy();
                }
                mlocationClient = null;
            }
        });// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        // 设置定位的类型为定位模式 ，可以由定位、跟随或地图根据面向方向旋转几种
        aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
    }

    private void setupRecyclerView(RecyclerView recyclerView) {
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
        //recyclerView.setAdapter(new FindAdapter(getContext(), items));
    }

    @Override
    public void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume ()，实现地图生命周期管理
        mMapView.onResume();
        System.out.println("onResume()执行了");
    }

    @Override
    public void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause ()，实现地图生命周期管理
        mMapView.onPause();
        System.out.println("onPause()执行了");
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，实现地图生命周期管理
        mMapView.onSaveInstanceState(outState);
        System.out.println("onSaveInstanceState()执行了");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        RxBus.get().unregister("temp", observable);
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mMapView.onDestroy();
        System.out.println("onPause()执行了");
    }

    /**
     * marker点击时跳动一下
     */
    public void jumpPoint(final Marker marker) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        Projection proj = aMap.getProjection();
        Point startPoint = proj.toScreenLocation(new LatLng(30.679879, 104.064855));
        startPoint.offset(0, -100);
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);
        final long duration = 1500;

        final Interpolator interpolator = new BounceInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
                double lng = t * new LatLng(30.679879, 104.064855).longitude + (1 - t)
                        * startLatLng.longitude;
                double lat = t * new LatLng(30.679879, 104.064855).latitude + (1 - t)
                        * startLatLng.latitude;
                marker.setPosition(new LatLng(lat, lng));
                if (t < 1.0) {
                    handler.postDelayed(this, 16);
                }
            }
        });
    }


    private int count = 1;
    Bitmap lastMarkerBitMap = null;

    /**
     * 从地上生长效果，实现思路
     * 在较短的时间内，修改marker的图标大小，从而实现动画<br>
     * 1.保存原始的图片；
     * 2.在原始图片上缩放得到新的图片，并设置给marker；
     * 3.回收上一张缩放后的图片资源；
     * 4.重复2，3步骤到时间结束；
     * 5.回收上一张缩放后的图片资源，设置marker的图标为最原始的图片；
     * <p>
     * 其中时间变化由AccelerateInterpolator控制
     *
     * @param marker
     */
    private void growInto(final Marker marker) {
        marker.setVisible(false);
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final long duration = 250;// 动画总时长
        final Bitmap bitMap = marker.getIcons().get(0).getBitmap();// BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
        final int width = bitMap.getWidth();
        final int height = bitMap.getHeight();

        final Interpolator interpolator = new AccelerateInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);

                if (t > 1) {
                    t = 1;
                }

                // 计算缩放比例
                int scaleWidth = (int) (t * width);
                int scaleHeight = (int) (t * height);
                if (scaleWidth > 0 && scaleHeight > 0) {

                    // 使用最原始的图片进行大小计算
                    marker.setIcon(BitmapDescriptorFactory.fromBitmap(Bitmap
                            .createScaledBitmap(bitMap, scaleWidth,
                                    scaleHeight, true)));
                    marker.setVisible(true);

                    // 因为替换了新的图片，所以把旧的图片销毁掉，注意在设置新的图片之后再销毁
                    if (lastMarkerBitMap != null
                            && !lastMarkerBitMap.isRecycled()) {
                        lastMarkerBitMap.recycle();
                    }

                    //第一次得到的缩放图片，在第二次回收，最后一次的缩放图片，在动画结束时回收
                    ArrayList<BitmapDescriptor> list = marker.getIcons();
                    if (list != null && list.size() > 0) {
                        // 保存旧的图片
                        lastMarkerBitMap = marker.getIcons().get(0).getBitmap();
                    }

                }

                if (t < 1.0 && count < 10) {
                    handler.postDelayed(this, 16);
                } else {
                    // 动画结束回收缩放图片，并还原最原始的图片
                    if (lastMarkerBitMap != null
                            && !lastMarkerBitMap.isRecycled()) {
                        lastMarkerBitMap.recycle();
                    }
                    marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitMap));
                    marker.setVisible(true);
                }
            }
        });
    }

}
